# app/utils/device_info_manager.py
import asyncio
import json
import logging
from typing import Dict

from fastapi import WebSocket
from sqlalchemy.orm import Session
from starlette.websockets import WebSocketDisconnect

from app.models.models import Device
from app.utils.device_cache import device_cache
from app.utils.ws_manager import ws_manager
from app.utils.ws_manager import device_info_manager

logger = logging.getLogger(__name__)

async def handle_device_info_websocket(websocket: WebSocket):
    """处理设备信息WebSocket连接"""
    await websocket.accept()

    try:
        while True:
            # 等待客户端消息
            data = await websocket.receive_text()
            logger.info(f"收到客户端消息: {data}")

            try:
                message = json.loads(data)
                dev_id = message.get("dev_id")
                action = message.get("action")

                if not dev_id:
                    await websocket.send_json({
                        "type": "error",
                        "message": "设备ID不能为空"
                    })
                    logger.warning(f"设备ID不能为空")
                    # 未提供设备ID，返回403
                    await websocket.close(code=403, reason="未提供设备ID")
                    return

                # 验证设备是否存在
                from app.core.database import get_device
                device = await get_device(dev_id)
                if not device:
                    # 设备不存在，返回403
                    await websocket.close(code=403, reason="设备不存在")
                    return

                # 连接到设备信息管理器
                await device_info_manager.connect(websocket, dev_id)

                if action == "get_device_info":
                    device_info = await get_device(dev_id)
                    if device_info:
                        await websocket.send_json({
                            "type": "device_info",
                            "dev_id": dev_id,
                            "data": device_info
                        })
                        logger.info(f"已发送设备信息: {dev_id}")
                    else:
                        await websocket.send_json({
                            "type": "error",
                            "message": "设备信息获取失败"
                        })
                        logger.warning(f"设备信息获取失败: {dev_id}")
                elif "command" in message:
                    # 通过设备连接发送命令
                    device_websocket = await ws_manager.get_device_connection(dev_id)
                    if device_websocket:
                        try:
                            # 发送命令到设备
                            await device_websocket.send_text(data)
                            logger.info(f"已发送命令到设备 {dev_id}: {message}")
                        except Exception as e:
                            logger.error(f"发送命令失败: {str(e)}")
                            await websocket.send_json({
                                "type": "error",
                                "dev_id": dev_id,
                                "message": f"发送命令失败: {str(e)}"
                            })
                    else:
                        await websocket.send_json({
                            "type": "error",
                            "dev_id": dev_id,
                            "message": "设备未连接"
                        })
                else:
                    # 未知操作，返回403
                    await websocket.close(code=403, reason="未知操作")
                    return
            except json.JSONDecodeError as e:
                # 无效的JSON格式，返回403
                await websocket.close(code=403, reason="无效的JSON格式")
                return

    except WebSocketDisconnect as e:
        logger.info(f"WebSocket连接断开: {e.code} - {e.reason}")
    except Exception as e:
        logger.error(f"处理WebSocket消息时发生错误: {e}")
        await websocket.close(code=1011, reason="服务器内部错误")


# 在设备状态更新函数中添加推送逻辑
async def update_device_status(dev_id: str, status_update: dict, db: Session):
    """更新设备状态并推送更新"""
    try:
        device = db.query(Device).filter(Device.dev_id == dev_id).first()
        if device:
            # 确保数值字段有效
            for key in ["cpu_usage", "mem_usage", "brightness", "volume"]:
                if key in status_update and status_update[key] == '':
                    status_update[key] = None

            # 更新设备状态
            for key, value in status_update.items():
                setattr(device, key, value)

            # 提交更改
            db.commit()

            # 获取更新后的设备数据
            updated_device = device.to_dict()

            # 更新缓存
            await device_cache.update_device(dev_id, updated_device)

            # 推送更新给所有订阅的客户端
            await device_info_manager.broadcast_device_info(dev_id, {
                "type": "device_update",
                "data": updated_device
            })

            return updated_device
        return None
    except Exception as e:
        db.rollback()
        logger.error(f"更新设备状态失败: {e}")
        return None